#include <sys_head.h>
#include "agr.h"
#include "pthread.h"

// argv[1] IP地址
// argv[2] 端口号

void Server(int Sock_fd);

// 读写线程
void *r_pthread(void *arg_fd);
void *w_pthread(void *arg_fd);

int main(int argc, char const *argv[])
{
    // 判断命令行参数
    if (argc < 2)
    {
        printf("参数错误:%s ip port\n" , argv[0]);
        return -1;
    }
    // 给定默认ip

    char ip_str[128];

    if ( 3 != argc )
    {
        
        strcpy( ip_str , "10.0.12.15");
    }
    else{
        
        strcpy( ip_str , argv[2]);
    }

    //  1、创建套接字
    int Sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == Sock_fd)
    {
        ERRLOG("socket erron");
        return -1;
    }
    //  2、填充服务器网络信息结构体
    struct sockaddr_in Sock_addr;
    Sock_addr.sin_family = AF_INET;                 // 选择 IPV4
    Sock_addr.sin_port = htons(atoi(argv[1]));      // 给定端口 // atoi 将字符串 转换成数字
    Sock_addr.sin_addr.s_addr = inet_addr(ip_str); // IP地址

    socklen_t Sock_size = sizeof(Sock_addr);

    //  3、将套接字与服务器的网络信息结构体绑定
    if (-1 == bind(Sock_fd, (struct sockaddr *)&Sock_addr, Sock_size))
    {
        ERRLOG("bind err");
        return -1;
    }

    //  4、将套接字设置城 监听状态

    if (-1 == listen(Sock_fd, 5))
    {
        ERRLOG("Sock_fd err");
        return -1;
    }
    //  5、阻塞等待客户端连接 accept

    int acc_fd = accept(Sock_fd, NULL, NULL);
    if (-1 == acc_fd)
    {
        ERRLOG("accept err");
        return -1;
    }

    //  6、数据收发 write read
    Server(acc_fd);

    //  7、关闭套接字  close
    close(acc_fd);
    close(Sock_fd);
    return 0;
}

void Server(int Sock_fd)
{
    agr info; // 协议
    char buf[1024];


    // 接收请求
    recv(Sock_fd , info.buf , sizeof(info.buf) , 0 );
    
    // 判断是否为下载请求
    if ( 1 != info.request.bytes )
    {
        puts("未接收到 下载请求");
        return ;
    }

    // 发送文件列表   用目录操作
    // 打开目录
    DIR * dir_ = opendir("file_app");

    struct dirent *entry;

    info.File_list.num = 0;

    while ((entry = readdir(dir_)) != NULL) {
        sprintf( buf, "%s", entry->d_name);
        // 不发送隐藏文件
        if ('.' == buf[0])
        {
            continue;
        }

        strcat(info.File_list.data , buf);
        info.File_list.num++;

        // 到达文件名最大存储
        if (7 == info.File_list.num)
        {
            break;
        }
    }

    info.File_list.bytes = 2;

    send(Sock_fd , info.buf , strlen(info.buf) , 0);


    // 接收文件名
    memset(info.buf , 0 , sizeof(info.buf));

    recv(Sock_fd , info.buf , sizeof(info.buf) , 0);
    
    if (3 != info.File_name.bytes)
    {
        printf("发送的信息不是文件名\n");
        return ;
    }
    
    // 打开文件
    memset(buf , 0 , sizeof(buf));

    sprintf(buf , "%s%s" , "./file_app/" , info.File_name.data );

    // 查看文件名

    printf("%s\n" , buf);


    int fd = open(buf , O_RDONLY );
    if (-1 == fd)
    {
        printf("文件打开失败\n");
    }
    
    lseek(fd , 0 , SEEK_SET);



    // 发送文件
    while (0 != read(fd , info.File_data.data , sizeof(info.File_data.data) - 1))
    {
        info.File_data.bytes = 4;
        write(Sock_fd , info.buf , strlen(info.buf));
        memset(info.buf , 0 , sizeof(info.buf));
    }

    
}


